Skip to content

WIP feat: rslib executor #3784

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft

WIP feat: rslib executor #3784

wants to merge 7 commits into from

Conversation

ScriptedAlchemy
Copy link
Member

@ScriptedAlchemy ScriptedAlchemy commented May 16, 2025

Description

This PR introduces a new Rslib Nx Plugin that provides executors for building and developing with Rslib, a framework-agnostic library building solution from the Rsbuild ecosystem.

Key Features

  • Build Executor (rslib:build): Builds libraries using Rslib with support for multiple formats (ESM, CJS, UMD)
  • Dev Executor (rslib:dev): Runs Rslib in development mode with hot reloading and Module Federation support
  • Echo Executor (rslib:echo): Simple testing executor for plugin validation

What's Included

1. Rslib Nx Plugin (tools/rslib-plugin/)

  • Full-featured Nx plugin with TypeScript support
  • Comprehensive executors for build and development workflows
  • JSON schemas for configuration validation
  • Built-in support for Module Federation development mode

2. Runtime Core Updates (packages/runtime-core/)

  • Migrated from custom build system to Rslib
  • Added rslib.config.ts configuration
  • Updated TypeScript configurations
  • Enhanced global type definitions

3. Example Implementation (apps/rslib-module/)

  • Demonstrates practical usage of the Rslib executor
  • Shows proper project configuration
  • Example of Module Federation setup with Rslib

Benefits

  • Framework Agnostic: Works with any library setup regardless of framework
  • Module Federation Ready: Built-in support for MF development workflows
  • Developer Experience: Hot reloading, watch mode, and comprehensive logging
  • Production Ready: Optimized builds with multiple output formats
  • Type Safe: Full TypeScript support with proper schema validation

Usage Example

{
  "targets": {
    "build": {
      "executor": "rslib:build",
      "options": {
        "configFile": "rslib.config.ts",
        "mode": "production"
      }
    },
    "dev": {
      "executor": "rslib:dev", 
      "options": {
        "mode": "mf-dev",
        "port": 3001
      }
    }
  }
}

This integration brings modern library building capabilities to the Module Federation ecosystem while maintaining compatibility with existing Nx workflows.

Related Issue

Addresses the need for a modern, efficient library building solution within the Module Federation ecosystem that supports both traditional library builds and Module Federation development workflows.

Types of changes

  • New feature (non-breaking change which adds functionality)
  • Docs change / refactoring / dependency upgrade

Checklist

  • I have added comprehensive documentation (README.md)
  • All executors include proper JSON schemas for validation
  • Example app demonstrates practical usage
  • Plugin follows Nx executor patterns and best practices
  • TypeScript definitions are properly configured
  • Module Federation development mode is supported

Copy link

netlify bot commented May 16, 2025

Deploy Preview for module-federation-docs failed. Why did it fail? →

Name Link
🔨 Latest commit e015986
🔍 Latest deploy log https://app.netlify.com/projects/module-federation-docs/deploys/687f113398865800092a7646

Copy link

changeset-bot bot commented May 16, 2025

⚠️ No Changeset found

Latest commit: e015986

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: Claude <[email protected]>
const args = ['rslib', 'build'];

if (options.configFile && options.configFile !== 'rslib.config.ts') {
args.push('--config', options.configFile);

Check warning

Code scanning / CodeQL

Unsafe shell command constructed from library input Medium

This array element which depends on
library input
is later used in a
shell command
.

Copilot Autofix

AI 23 days ago

To fix the issue, we should replace the unsafe exec function with the safer execFile function from the child_process module. Instead of constructing a single string command, we should pass the command and arguments as separate array elements to execFile. This approach avoids shell interpretation and mitigates the risk of command injection.

Specifically:

  1. Replace the args.join(' ') logic with a direct call to execFile, passing the args array (split into the command and its arguments).
  2. Remove the need for command as a single string.
  3. Update the promisify(exec) call to promisify(execFile).

Suggested changeset 1
tools/rslib-plugin/src/executors/build/executor.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/tools/rslib-plugin/src/executors/build/executor.ts b/tools/rslib-plugin/src/executors/build/executor.ts
--- a/tools/rslib-plugin/src/executors/build/executor.ts
+++ b/tools/rslib-plugin/src/executors/build/executor.ts
@@ -1,5 +1,5 @@
 import type { ExecutorContext } from '@nx/devkit';
-import { exec } from 'child_process';
+import { execFile } from 'child_process';
 import { promisify } from 'util';
 import { join } from 'path';
 
@@ -44,13 +44,11 @@
   // Note: --mode option not supported in current rslib version
   // Environment will be set via NODE_ENV instead
 
-  const command = args.join(' ');
-
   try {
-    console.info(`Running: ${command}`);
+    console.info(`Running: ${args.join(' ')}`);
     console.info(`Working directory: ${join(context.root, projectRoot)}`);
 
-    const { stdout, stderr } = await promisify(exec)(command, {
+    const { stdout, stderr } = await promisify(execFile)(args[0], args.slice(1), {
       cwd: join(context.root, projectRoot),
       env: {
         ...process.env,
EOF
@@ -1,5 +1,5 @@
import type { ExecutorContext } from '@nx/devkit';
import { exec } from 'child_process';
import { execFile } from 'child_process';
import { promisify } from 'util';
import { join } from 'path';

@@ -44,13 +44,11 @@
// Note: --mode option not supported in current rslib version
// Environment will be set via NODE_ENV instead

const command = args.join(' ');

try {
console.info(`Running: ${command}`);
console.info(`Running: ${args.join(' ')}`);
console.info(`Working directory: ${join(context.root, projectRoot)}`);

const { stdout, stderr } = await promisify(exec)(command, {
const { stdout, stderr } = await promisify(execFile)(args[0], args.slice(1), {
cwd: join(context.root, projectRoot),
env: {
...process.env,
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant